var Pool = require('pg-pool')
const config = require("./config")
const log4 = require('../log4')

class Func {
  constructor () {
    this.sqlText = ''
    this.paramsValueArr = []
    this.myPool = new Pool(config)
  }
  /**
   * @function 创建SQL语句
   * @param {String} func 方法名
   * @param {String} table 表名
   * @param {Object|Array} params 要插入/更新，查询的参数
   * @param {Object} query 查询条件
   * @description 方法如下
   * query: 查询
   * insert: 插入
   * update: 更新
   * remove: 逻辑删除
   * none: 直接执行
   */
  createSqlText ({func, table, params, sql}) { 
    // 生成sql语句
    if (func === 'query') {
      this.sqlText = `select ${params.join(',')} from ${table}`
      this.paramsValueArr = []
    } else if (func === 'insert') {
      let paramsArr = []
      let paramsValue = []
      for(let i in params) {
        paramsArr.push(`${i}`)
        paramsValue.push(`${params[i]}`)
      }
      this.sqlText = `insert into ${table} (${paramsArr.join(' , ')}) VALUES (${[...`${this.paramsValueArr.length + 1}`.repeat(paramsValue.length)].join(',')})`
      this.paramsValueArr = paramsValue
    } else if (func === 'update') {
      let paramsArr = []
      let paramsValue = []
      for(let i in params) {
        paramsArr.push(`${i} = ${paramsValue.length + 1}`)
        paramsValue.push(params[i])
      }
      this.sqlText = `update ${table} set ${paramsArr.join(' , ')}`
      this.paramsValueArr = paramsValue
    } else if (func === 'remove') {
      this.sqlText = `update ${table} set enable = 0`
      this.paramsValueArr = []
    } else if (func === 'none') {
      this.sqlText = sql
      this.paramsValueArr = []
    }
    return this
  }
  where (query) {
    // 生成where
    if (query.length > 0) {
      let queryArr = []
      for(let i in query) {
        if (query[i].type === 'like') {
          queryArr.push(`${query[i].name} like ${this.paramsValueArr.length + 1}`)
          this.paramsValueArr.push(query[i].value)
        } else if (query[i].type === 'in') {
          queryArr.push(`${query[i].name} in (${this.paramsValueArr.length + 1})`)
          this.paramsValueArr.push(query[i].value.join(','))
        } else {
          queryArr.push(`${query[i].name} = ${this.paramsValueArr.length + 1}`)
          this.paramsValueArr.push(query[i].value)
        }
      }
      this.sqlText = `${this.sqlText} where  ${queryArr.join(' and ')}`
    }
    return this
  }
  order (order) {
    // 排序
    if (order) {
      let str = `order by `
      let arr = []
      for(let i in order) {
        arr.push(`${i} ${order[i]}`)
      }
      str = `${str}${arr.join(',')}`
      this.sqlText = `${sql} ${str}${arr.join(',')}`
    } else {
      this.sqlText = `${sql} order by create_time asc`
    }
    return this
  }
  limit (limit) {
    // 生成limit
    if (limit) {
      let str = `limit ${limit[0] || 0}, ${limit[1] || 10}`
      this.sqlText = `${this.sqlText} ${str}`
    }
    return this
  }
  /**
   * @function 获取连接池节点
   */
  getClient () {
    return new Promise((resolve, reject) => {
      this.myPool.connect().then((client) => {
        resolve(client)
      })
    })
  }
  /**
   * @function 执行sql 语句
   * @param {Object} client 数据库连接
   * @param {Boolean} isRelease 是否在执行完后关闭数据库
   */
  run (client, isRelease = true) {
    let sql = this.sqlText
    let paramsValueArr = this.paramsValueArr
    return new Promise((resolve, reject) => {
      client.query(sql, paramsValueArr, (err, result) => {
        // 默认执行完毕关闭释放连接
        if (isRelease) {
          client.release()
        }
        // 处理结果
        if (err) {
          log4.error(err)
          reject()
        }
        resolve(result.rows)
      })
    })
  }
  /**
   * @function 释放连接
   * @param {Object} client 数据库连接
   */
  release (client) {
    client.release()
  }
  /**
   * @function 获取事务节点
   * @param {Object} client 数据库连接
   */
  async getTransactionClient (client) {
    await this.myPool.acquire().then((client) => {
      client.beginTransaction(err => {
        if (err) {
          log4.error(err)
          return false
        }
        return client
      })
    })
  }
  /**
   * @function 事务提交
   */
  commit (client) {
    client.commit(err => {
      if (err) {
        client.rollback(function(err) {
          if (err) {
            log4.error(err)
            return false
          }
        })
      }
    })
  }
  /**
   * @function 事务回滚
   */
  rollback(client) {
    client.rollback((err) => {
      if (err) {
        log4.error(err)
      }
    })
  }
}

// acquire connection - Promise is resolved
// once a resource becomes available
module.exports = Func
